home *** CD-ROM | disk | FTP | other *** search
/ Aminet 2 / Aminet AMIGA CDROM (1994)(Walnut Creek)[Feb 1994][W.O. 44790-1].iso / Aminet / comm / term / term34Source.lha / termStatusDisplay.c < prev    next >
C/C++ Source or Header  |  1993-07-16  |  46KB  |  2,053 lines

  1. /*
  2. **    termStatusDisplay.c
  3. **
  4. **    Status information display routines
  5. **
  6. **    Copyright © 1990-1993 by Olaf `Olsen' Barthel & MXM
  7. **        All Rights Reserved
  8. */
  9.  
  10. #include "termGlobal.h"
  11.  
  12.     /* The information to be displayed. */
  13.  
  14. enum    {    INFO_STATUS,INFO_FONT,INFO_PROTOCOL,INFO_EMULATION,INFO_BAUDRATE,
  15.         INFO_PARAMETERS,INFO_CURRENTTIME,INFO_ONLINETIME,INFO_ONLINECOST };
  16.  
  17.     /* The current status line display mode. */
  18.  
  19. enum    {    MODE_SCREEN_NORMAL,MODE_SCREEN_COMPRESSED,MODE_WB_NORMAL,MODE_WB_COMPRESSED };
  20.  
  21.     /* Enumerated text boxes. */
  22.  
  23. enum    {    STATUSBOX_STATUS_FONT,STATUSBOX_PROTOCOL_TERMINAL,
  24.         STATUSBOX_RATE_PARAMETERS,STATUSBOX_TIME_ONLINE };
  25.  
  26.     /* The tags our private status gadget class responds to. */
  27.  
  28. #define SG_Status    (TAG_USER+1)
  29. #define SG_Font        (TAG_USER+2)
  30. #define SG_Protocol    (TAG_USER+3)
  31. #define SG_Emulation    (TAG_USER+4)
  32. #define SG_BaudRate    (TAG_USER+5)
  33. #define SG_Parameters    (TAG_USER+6)
  34. #define SG_CurrentTime    (TAG_USER+7)
  35. #define SG_OnlineTime    (TAG_USER+8)
  36. #define SG_OnlineCost    (TAG_USER+9)
  37.  
  38.     /* Special private information maintained and required
  39.      * by the status gadget class.
  40.      */
  41.  
  42. struct StatusInfo
  43. {
  44.     struct TextBox        *BoxArray[4],
  45.                 *BoxList;
  46.  
  47.     LONG             FullWidth;
  48.     LONG             FirstColumn;
  49.  
  50.     UWORD             Mask;
  51.     UWORD             Mode;
  52.  
  53.     LONG             LastWidth;
  54.  
  55.     UBYTE             Strings[8][20];
  56.  
  57.     struct SignalSemaphore     Semaphore;
  58.  
  59.     LONG             WindowWidth,
  60.                  WindowHeight,
  61.                  WindowFlags;
  62. };
  63.  
  64.     /* The status server passes this structure to the
  65.      * rendering routine if the status information
  66.      * is to be updated.
  67.      */
  68.  
  69. struct ObjectCarrier
  70. {
  71.     struct RastPort     *RPort;
  72.     struct TextBox    **BoxArray;
  73. };
  74.  
  75.     /* A custom message type for the display update server. */
  76.  
  77. struct UpdateMessage
  78. {
  79.     struct Message    VanillaMessage;
  80.  
  81.     APTR        Object;
  82.     UBYTE        Mode,
  83.             Type;
  84. };
  85.  
  86.     /* The following static strings are displayed in the status
  87.      * window.
  88.      */
  89.  
  90. STATIC STRPTR    ConfigFont[3],
  91.         ConfigEmulation[6],
  92.         ConfigParity[6],
  93.         ConfigStatus[8];
  94.  
  95.     /* Width of the status line text, required in case the user interface
  96.      * font happens to be proportional-spaced.
  97.      */
  98.  
  99. STATIC LONG             StatusLineWidth;
  100.  
  101.     /* Our local private status gadget class. */
  102.  
  103. STATIC struct IClass        *StatusGadgetClass;
  104.  
  105.     /* The status display update task. */
  106.  
  107. STATIC struct Task        *StatusDisplayTask;
  108. STATIC struct MsgPort        *StatusDisplayPort;
  109.  
  110.     /* Prototypes for this module. */
  111.  
  112. STATIC ULONG            SetStatusGadget(struct IClass *class,Object *object,struct opSet *SetInfo);
  113. STATIC ULONG            GetStatusGadget(struct IClass *class,Object *object,struct opGet *GetInfo);
  114. STATIC ULONG            RenderStatusGadget(struct IClass *class,Object *object,struct gpRender *RenderInfo);
  115. STATIC ULONG            DelStatusGadget(struct IClass *class,Object *object,Msg msg);
  116. STATIC ULONG            NewStatusGadget(struct IClass *class,Object *object,struct opSet *SetMethod);
  117. STATIC ULONG __saveds __asm    StatusGadgetDispatch(register __a0 struct IClass *class,register __a2 Object *object,register __a1 Msg msg);
  118. STATIC VOID            FreeStatusGadgetClass(VOID);
  119. STATIC BYTE            NewStatusGadgetClass(VOID);
  120.  
  121.     /* GetStatusGadget():
  122.      *
  123.      *    Query information on the status gadget.
  124.      */
  125.  
  126. STATIC ULONG
  127. GetStatusGadget(struct IClass *class,Object *object,struct opGet *GetInfo)
  128. {
  129.     struct StatusInfo *StatusInfo = INST_DATA(class,object);
  130.  
  131.     switch(GetInfo -> opg_AttrID)
  132.     {
  133.         case SGA_FullWidth:
  134.  
  135.             *GetInfo -> opg_Storage = (ULONG)StatusInfo -> FullWidth;
  136.             return(1);
  137.  
  138.         default:
  139.  
  140.             return(DoSuperMethodA(class,object,(Msg)GetInfo));
  141.     }
  142. }
  143.  
  144.     /* SetStatusGadget():
  145.      *
  146.      *    Set certain attributes of the status gadget.
  147.      */
  148.  
  149. STATIC ULONG
  150. SetStatusGadget(struct IClass *class,Object *object,struct opSet *SetInfo)
  151. {
  152.     struct StatusInfo    *StatusInfo = INST_DATA(class,object);
  153.     LONG             i,j;
  154.     struct RastPort        *RPort;
  155.     struct TagItem        *Tag;
  156.  
  157.     DoSuperMethodA(class,object,(Msg)SetInfo);
  158.  
  159.         /* Make sure that the information is available and
  160.          * nobody else tries to modify it.
  161.          */
  162.  
  163.     ObtainSemaphore(&StatusInfo -> Semaphore);
  164.  
  165.         /* Obtain the new text to be displayed in the gadget. */
  166.  
  167.     for(i = SG_Status, j = 0 ; i <= SG_OnlineCost ; i++, j++)
  168.     {
  169.         if(Tag = FindTagItem(i,SetInfo -> ops_AttrList))
  170.         {
  171.             strcpy(StatusInfo -> Strings[j],(STRPTR)Tag -> ti_Data);
  172.  
  173.             StatusInfo -> Mask |= (1 << j);
  174.         }
  175.     }
  176.  
  177.         /* Release the lock. */
  178.  
  179.     ReleaseSemaphore(&StatusInfo -> Semaphore);
  180.  
  181.         /* Kluge! */
  182.  
  183.     if(Kick30)
  184.         return(1);
  185.  
  186.         /* Obtain the drawing area lock. */
  187.  
  188.     if(RPort = ObtainGIRPort(SetInfo -> ops_GInfo))
  189.     {
  190.             /* Normal, uncompressed status line? */
  191.  
  192.         if(StatusInfo -> Mode == MODE_WB_NORMAL)
  193.         {
  194.                 /* Take a look at the strings which have
  195.                  * changed and render the corresponding
  196.                  * text.
  197.                  */
  198.  
  199.             for(i = 0 ; i < 8 ; i++)
  200.             {
  201.                 if(StatusInfo -> Mask & (1 << i))
  202.                 {
  203.                     SZ_SetLine(RPort,StatusInfo -> BoxArray[i / 2],i % 2,StatusInfo -> Strings[i]);
  204.  
  205.                     StatusInfo -> Mask &= ~(1 << i);
  206.                 }
  207.             }
  208.         }
  209.         else
  210.         {
  211.             STATIC BYTE Offsets[8] =
  212.             {
  213.                  0,
  214.                 -1,
  215.                 26,
  216.                 11,
  217.                 40,
  218.                 53,
  219.                 61,
  220.                 72
  221.             };
  222.  
  223.             struct Gadget    *Gadget;
  224.             UBYTE         LineBuffer[90];
  225.             WORD         i,j,k;
  226.             LONG         Width,
  227.                      Left,
  228.                      Top;
  229.  
  230.                 /* Get the real gadget. */
  231.  
  232.             Gadget = (struct Gadget *)object;
  233.  
  234.                 /* Fill the line with defaults. */
  235.  
  236.             strcpy(LineBuffer,"         ·              ·             ·            ·       ·          ·         ");
  237.  
  238.                 /* Add the information strings. */
  239.  
  240.             for(i = 0 ; i < 8 ; i++)
  241.             {
  242.                 if(Offsets[i] >= 0)
  243.                 {
  244.                     j = strlen(StatusInfo -> Strings[i]);
  245.  
  246.                     for(k = 0 ; k < j ; k++)
  247.                         LineBuffer[Offsets[i] + k] = StatusInfo -> Strings[i][k];
  248.                 }
  249.             }
  250.  
  251.                 /* Determine the pixel width of the string. */
  252.  
  253.             Width = TextLength(RPort,LineBuffer,80);
  254.  
  255.                 /* Get the rendering top offset. */
  256.  
  257.             Top = SetInfo -> ops_GInfo -> gi_Window -> Height + Gadget -> TopEdge;
  258.  
  259.             SetDrMd(RPort,JAM2);
  260.  
  261.                 /* Are we to clear the area the last rendering
  262.                  * operation obscured?
  263.                  */
  264.  
  265.             if(StatusInfo -> LastWidth && StatusInfo -> LastWidth != Width)
  266.             {
  267.                 Left = (SetInfo -> ops_GInfo -> gi_Window -> Width - StatusInfo -> LastWidth) / 2;
  268.  
  269.                     /* Set the approriate rendering pen. */
  270.  
  271.                 if(SetInfo -> ops_GInfo -> gi_Window -> Flags & WFLG_WINDOWACTIVE)
  272.                     SetAPen(RPort,SetInfo -> ops_GInfo -> gi_DrInfo -> dri_Pens[FILLPEN]);
  273.                 else
  274.                     SetAPen(RPort,SetInfo -> ops_GInfo -> gi_DrInfo -> dri_Pens[BACKGROUNDPEN]);
  275.  
  276.                     /* Clear the area. */
  277.  
  278.                 RectFill(RPort,Left,Top,Left + StatusInfo -> LastWidth - 1,Top + Gadget -> Height - 3);
  279.             }
  280.  
  281.                 /* Set the approriate rendering pens. */
  282.  
  283.             if(SetInfo -> ops_GInfo -> gi_Window -> Flags & WFLG_WINDOWACTIVE)
  284.             {
  285.                 SetAPen(RPort,SetInfo -> ops_GInfo -> gi_DrInfo -> dri_Pens[FILLTEXTPEN]);
  286.                 SetBPen(RPort,SetInfo -> ops_GInfo -> gi_DrInfo -> dri_Pens[FILLPEN]);
  287.             }
  288.             else
  289.             {
  290.                 SetAPen(RPort,SetInfo -> ops_GInfo -> gi_DrInfo -> dri_Pens[TEXTPEN]);
  291.                 SetBPen(RPort,SetInfo -> ops_GInfo -> gi_DrInfo -> dri_Pens[BACKGROUNDPEN]);
  292.             }
  293.  
  294.                 /* Remember the text pixel width. */
  295.  
  296.             StatusInfo -> LastWidth = Width;
  297.  
  298.                 /* Display the status line. */
  299.  
  300.             Move(RPort,(SetInfo -> ops_GInfo -> gi_Window -> Width - StatusInfo -> LastWidth) / 2,Top + RPort -> Font -> tf_Baseline);
  301.             Text(RPort,LineBuffer,80);
  302.         }
  303.  
  304.             /* Release the rendering area. */
  305.  
  306.         ReleaseGIRPort(RPort);
  307.     }
  308.  
  309.     return(1);
  310. }
  311.  
  312.     /* RenderStatusGadget():
  313.      *
  314.      *    Redraw the entire status gadget.
  315.      */
  316.  
  317. STATIC ULONG
  318. RenderStatusGadget(struct IClass *class,Object *object,struct gpRender *RenderInfo)
  319. {
  320.     struct StatusInfo    *StatusInfo    = INST_DATA(class,object);
  321.     struct RastPort        *RPort        = RenderInfo -> gpr_RPort;
  322.     BYTE             MustRender,
  323.                  UpdateOnly;
  324.     ULONG             Width    = RenderInfo -> gpr_GInfo -> gi_Window -> Width,
  325.                  Height    = RenderInfo -> gpr_GInfo -> gi_Window -> Height,
  326.                  Flags    = RenderInfo -> gpr_GInfo -> gi_Window -> Flags;
  327.  
  328.     LONG             i;
  329.  
  330.         /* Kluge! */
  331.  
  332.     if(Kick30)
  333.     {
  334.         if(StatusInfo -> Mask)
  335.             UpdateOnly = MustRender = TRUE;
  336.         else
  337.             UpdateOnly = MustRender = FALSE;
  338.  
  339.         if(StatusInfo -> WindowWidth != Width || StatusInfo -> WindowHeight != Height || ((Flags & WFLG_WINDOWACTIVE) != StatusInfo -> WindowFlags))
  340.         {
  341.             MustRender    = TRUE;
  342.             UpdateOnly    = FALSE;
  343.  
  344.             StatusInfo -> WindowWidth    = Width;
  345.             StatusInfo -> WindowHeight    = Height;
  346.             StatusInfo -> WindowFlags    = Flags & WFLG_WINDOWACTIVE;
  347.             StatusInfo -> Mask        = 0xFF;
  348.         }
  349.     }
  350.     else
  351.     {
  352.         UpdateOnly = MustRender = TRUE;
  353.  
  354.         StatusInfo -> Mask |= 0xFF;
  355.     }
  356.  
  357.     if(MustRender)
  358.     {
  359.             /* Normal, uncompressed display? */
  360.     
  361.         if(StatusInfo -> Mode == MODE_WB_NORMAL)
  362.         {
  363.                 /* Refresh the entire imagery (the default)? */
  364.     
  365.             if(RenderInfo -> gpr_Redraw == GREDRAW_REDRAW && !UpdateOnly)
  366.             {
  367.                 struct Gadget    *Gadget = (struct Gadget *)object;
  368.                 LONG         X;
  369.     
  370.                     /* Don't let anyone modify the text. */
  371.     
  372.                 ObtainSemaphore(&StatusInfo -> Semaphore);
  373.     
  374.                     /* Get the new gadget left offset. */
  375.     
  376.                 if((X = (RenderInfo -> gpr_GInfo -> gi_Window -> Width - StatusInfo -> FullWidth) / 2) < 0)
  377.                     X = 0;
  378.     
  379.                 X += StatusInfo -> FirstColumn - SZ_GetBoxInfo(StatusInfo -> BoxList,BOX_LEFT);
  380.     
  381.                     /* Move the status line to the new location. */
  382.     
  383.                 SZ_SetBoxes(StatusInfo -> BoxList,-1,RenderInfo -> gpr_GInfo -> gi_Window -> Height + Gadget -> TopEdge + 1);
  384.     
  385.                 if(X)
  386.                     SZ_MoveBoxes(StatusInfo -> BoxList,X,0);
  387.     
  388.                     /* Set the box title rendering pen. */
  389.     
  390.                 if(Flags & WFLG_WINDOWACTIVE)
  391.                     SZ_SetTitlePen(StatusInfo -> BoxList,RenderInfo -> gpr_GInfo -> gi_DrInfo -> dri_Pens[FILLTEXTPEN],RenderInfo -> gpr_GInfo -> gi_DrInfo -> dri_Pens[FILLPEN]);
  392.                 else
  393.                     SZ_SetTitlePen(StatusInfo -> BoxList,RenderInfo -> gpr_GInfo -> gi_DrInfo -> dri_Pens[TEXTPEN],RenderInfo -> gpr_GInfo -> gi_DrInfo -> dri_Pens[BACKGROUNDPEN]);
  394.     
  395.                     /* Redraw the boxes. */
  396.     
  397.                 SZ_DrawBoxes(RPort,StatusInfo -> BoxList);
  398.     
  399.                     /* Redraw all the strings. */
  400.     
  401.                 ReleaseSemaphore(&StatusInfo -> Semaphore);
  402.             }
  403.     
  404.                 /* Update the information which has changed. */
  405.     
  406.             for(i = 0 ; i < 8 ; i++)
  407.             {
  408.                 if(StatusInfo -> Mask & (1 << i))
  409.                 {
  410.                     SZ_SetLine(RPort,StatusInfo -> BoxArray[i / 2],i % 2,StatusInfo -> Strings[i]);
  411.     
  412.                     StatusInfo -> Mask &= ~(1 << i);
  413.                 }
  414.             }
  415.         }
  416.         else
  417.         {
  418.             STATIC BYTE Offsets[8] =
  419.             {
  420.                  0,
  421.                 -1,
  422.                 26,
  423.                 11,
  424.                 40,
  425.                 53,
  426.                 61,
  427.                 72
  428.             };
  429.     
  430.             struct Gadget    *Gadget;
  431.             UBYTE         LineBuffer[90];
  432.             WORD         i,j,k;
  433.             LONG         Width,
  434.                      Left,
  435.                      Top;
  436.     
  437.                 /* Grab the access semaphore. */
  438.     
  439.             ObtainSemaphore(&StatusInfo -> Semaphore);
  440.     
  441.                 /* Get the real gadget info. */
  442.     
  443.             Gadget = (struct Gadget *)object;
  444.     
  445.                 /* Fill the line buffer with defaults. */
  446.     
  447.             strcpy(LineBuffer,"         ·              ·             ·            ·       ·          ·         ");
  448.     
  449.                 /* Fill in the information strings. */
  450.     
  451.             for(i = 0 ; i < 8 ; i++)
  452.             {
  453.                 if(Offsets[i] >= 0)
  454.                 {
  455.                     j = strlen(StatusInfo -> Strings[i]);
  456.     
  457.                     for(k = 0 ; k < j ; k++)
  458.                         LineBuffer[Offsets[i] + k] = StatusInfo -> Strings[i][k];
  459.                 }
  460.             }
  461.     
  462.                 /* Determine the pixel width of the line. */
  463.     
  464.             Width = TextLength(RPort,LineBuffer,80);
  465.     
  466.                 /* Get the line top offset. */
  467.     
  468.             Top = RenderInfo -> gpr_GInfo -> gi_Window -> Height + Gadget -> TopEdge;
  469.     
  470.             SetDrMd(RPort,JAM2);
  471.     
  472.                 /* Clear the previously written text if necessary. */
  473.     
  474.             if(StatusInfo -> LastWidth && RenderInfo -> gpr_Redraw != GREDRAW_REDRAW)
  475.             {
  476.                 Left = (RenderInfo -> gpr_GInfo -> gi_Window -> Width - StatusInfo -> LastWidth) / 2;
  477.     
  478.                 if(RenderInfo -> gpr_GInfo -> gi_Window -> Flags & WFLG_WINDOWACTIVE)
  479.                     SetAPen(RPort,RenderInfo -> gpr_GInfo -> gi_DrInfo -> dri_Pens[FILLPEN]);
  480.                 else
  481.                     SetAPen(RPort,RenderInfo -> gpr_GInfo -> gi_DrInfo -> dri_Pens[BACKGROUNDPEN]);
  482.     
  483.                 RectFill(RPort,Left,Top,Left + StatusInfo -> LastWidth - 1,Top + Gadget -> Height - 3);
  484.             }
  485.     
  486.                 /* Set the approriate rendering colours. */
  487.     
  488.             if(RenderInfo -> gpr_GInfo -> gi_Window -> Flags & WFLG_WINDOWACTIVE)
  489.             {
  490.                 SetAPen(RPort,RenderInfo -> gpr_GInfo -> gi_DrInfo -> dri_Pens[FILLTEXTPEN]);
  491.                 SetBPen(RPort,RenderInfo -> gpr_GInfo -> gi_DrInfo -> dri_Pens[FILLPEN]);
  492.             }
  493.             else
  494.             {
  495.                 SetAPen(RPort,RenderInfo -> gpr_GInfo -> gi_DrInfo -> dri_Pens[TEXTPEN]);
  496.                 SetBPen(RPort,RenderInfo -> gpr_GInfo -> gi_DrInfo -> dri_Pens[BACKGROUNDPEN]);
  497.             }
  498.     
  499.                 /* Remember last pixel width. */
  500.     
  501.             StatusInfo -> LastWidth = Width;
  502.     
  503.                 /* Render the status line. */
  504.     
  505.             Move(RPort,(RenderInfo -> gpr_GInfo -> gi_Window -> Width - StatusInfo -> LastWidth) / 2,Top + RPort -> Font -> tf_Baseline);
  506.             Text(RPort,LineBuffer,80);
  507.     
  508.                 /* Release the lock. */
  509.     
  510.             ReleaseSemaphore(&StatusInfo -> Semaphore);
  511.         }
  512.     }
  513.  
  514.     return(0);
  515. }
  516.  
  517.     /* DelStatusGadget():
  518.      *
  519.      *    Deallocate the status gadget.
  520.      */
  521.  
  522. STATIC ULONG
  523. DelStatusGadget(struct IClass *class,Object *object,Msg msg)
  524. {
  525.     struct StatusInfo *StatusInfo = INST_DATA(class,object);
  526.  
  527.     if(StatusInfo -> BoxList)
  528.         SZ_FreeBoxes(StatusInfo -> BoxList);
  529.  
  530.     return(DoSuperMethodA(class,object,msg));
  531. }
  532.  
  533.     /* NewStatusGadget():
  534.      *
  535.      *    Create a new status gadget.
  536.      */
  537.  
  538. STATIC ULONG
  539. NewStatusGadget(struct IClass *class,Object *object,struct opSet *SetMethod)
  540. {
  541.     struct Gadget    *NewGadget;
  542.     struct TagItem    *OldTags,*Item;
  543.     LONG         NewItems[5][2],
  544.              Height,
  545.              Mode;
  546.  
  547.         /* Remember the old tag item list, as we will change it. */
  548.  
  549.     OldTags = SetMethod -> ops_AttrList;
  550.  
  551.         /* Determine the status line mode (compressed or normal). */
  552.  
  553.     if(Item = FindTagItem(SGA_Mode,OldTags))
  554.     {
  555.         switch(Item -> ti_Data)
  556.         {
  557.             case MODE_WB_NORMAL:
  558.             case MODE_WB_COMPRESSED:
  559.  
  560.                 Mode = Item -> ti_Data;
  561.                 break;
  562.  
  563.             default:
  564.  
  565.                 return(NULL);
  566.         }
  567.     }
  568.     else
  569.         return(NULL);
  570.  
  571.         /* Set up the defaults, note that this class
  572.          * implementation can, strictly speaking, not
  573.          * be considered reentrant.
  574.          */
  575.  
  576.     SZ_SizeSetup(DefaultPubScreen,&UserFont,TRUE);
  577.  
  578.         /* Determine object height. */
  579.  
  580.     if(Mode == MODE_WB_NORMAL)
  581.         Height = 3 + SZ_BoxHeight(2);
  582.     else
  583.         Height = 2 + UserFontHeight;
  584.  
  585.         /* Build new tag item list. */
  586.  
  587.     NewItems[0][0] = GA_RelBottom;
  588.     NewItems[0][1] = -Height;
  589.     NewItems[1][0] = GA_Height;
  590.     NewItems[1][1] = Height;
  591.     NewItems[2][0] = GA_BottomBorder;
  592.     NewItems[2][1] = TRUE;
  593.     NewItems[3][0] = GA_Highlight;
  594.     NewItems[3][1] = GFLG_GADGHNONE;
  595.     NewItems[4][0] = TAG_MORE;
  596.     NewItems[4][1] = (LONG)OldTags;
  597.  
  598.         /* Install the new tag item list. */
  599.  
  600.     SetMethod -> ops_AttrList = (struct TagItem *)NewItems;
  601.  
  602.         /* Create the new object. */
  603.  
  604.     if(NewGadget = (struct Gadget *)DoSuperMethodA(class,object,(Msg)SetMethod))
  605.     {
  606.         struct StatusInfo    *StatusInfo = INST_DATA(class,NewGadget);
  607.         LONG             SizeGadgetWidth;
  608.  
  609.         StatusInfo -> WindowWidth = StatusInfo -> WindowHeight = 0;
  610.  
  611.             /* Determine the width of the window sizing gadget,
  612.              * hopefully these values are never going to be
  613.              * changed.
  614.              */
  615.  
  616.         if(DefaultPubScreen -> Flags & SCREENHIRES)
  617.             SizeGadgetWidth = SIZE_GADGET_WIDTH_HIGH;
  618.         else
  619.             SizeGadgetWidth = SIZE_GADGET_WIDTH_LOW;
  620.  
  621.             /* Clear the extra information area. */
  622.  
  623.         memset(StatusInfo,0,sizeof(struct StatusInfo));
  624.  
  625.             /* Initialize the signal semaphore. */
  626.  
  627.         InitSemaphore(&StatusInfo -> Semaphore);
  628.  
  629.             /* Is it the `big one'? */
  630.  
  631.         if((StatusInfo -> Mode = Mode) == MODE_WB_NORMAL)
  632.         {
  633.             WORD         ColumnLeft[4],
  634.                      ColumnWidth[4];
  635.             struct TextBox    *Box;
  636.             LONG         i,Max = 0,Len,FullWidth,BoxCounter = 0;
  637.  
  638.             ColumnLeft[0] = SZ_LeftOffsetN(MSG_TERMSTATUSDISPLAY_STATUS_TXT,MSG_TERMSTATUSDISPLAY_FONT_TXT,-1);
  639.             ColumnLeft[1] = SZ_LeftOffsetN(MSG_TERMSTATUSDISPLAY_PROTOCOL_TXT,MSG_TERMSTATUSDISPLAY_TERMINAL_TXT,-1);
  640.             ColumnLeft[2] = SZ_LeftOffsetN(MSG_TERMSTATUSDISPLAY_BAUDRATE_TXT,MSG_TERMSTATUSDISPLAY_PARAMETERS_TXT,-1);
  641.             ColumnLeft[3] = SZ_LeftOffsetN(MSG_TERMSTATUSDISPLAY_TIME_TXT,MSG_TERMSTATUSDISPLAY_ONLINE_TXT,-1);
  642.  
  643.             for(i = 0 ; ConfigStatus[i] ; i++)
  644.             {
  645.                 if((Len = SZ_BoxWidth(strlen(ConfigStatus[i]))) > Max)
  646.                     Max = Len;
  647.             }
  648.  
  649.             for(i = 0 ; ConfigFont[i] ; i++)
  650.             {
  651.                 if((Len = SZ_BoxWidth(strlen(ConfigFont[i]))) > Max)
  652.                     Max = Len;
  653.             }
  654.  
  655.             ColumnWidth[0] = Max;
  656.  
  657.             Max = SZ_BoxWidth(12);
  658.  
  659.             for(i = 0 ; ConfigEmulation[i] ; i++)
  660.             {
  661.                 if((Len = SZ_BoxWidth(strlen(ConfigEmulation[i]))) > Max)
  662.                     Max = Len;
  663.             }
  664.  
  665.             ColumnWidth[1] = Max;
  666.  
  667.             Max = SZ_BoxWidth(10);
  668.  
  669.             for(i = 0 ; ConfigParity[i] ; i++)
  670.             {
  671.                 if((Len = SZ_BoxWidth(4 + strlen(ConfigParity[i]))) > Max)
  672.                     Max = Len;
  673.             }
  674.  
  675.             ColumnWidth[2] = Max;
  676.  
  677.             ColumnWidth[3] = SZ_BoxWidth(8);
  678.  
  679.             FullWidth = 0;
  680.  
  681.             for(i = 0 ; i < 4 ; i++)
  682.                 FullWidth += ColumnWidth[i] + ColumnLeft[i];
  683.  
  684.             FullWidth += 3 * InterWidth;
  685.  
  686.             StatusInfo -> FullWidth        = FullWidth + 2 * SizeGadgetWidth;
  687.             StatusInfo -> FirstColumn    = ColumnLeft[0];
  688.  
  689.             if(FullWidth > DefaultPubScreen -> Width)
  690.                 SZ_SetLeftEdge(ColumnLeft[0]);
  691.             else
  692.                 SZ_SetLeftEdge((DefaultPubScreen -> Width - FullWidth) / 2 + ColumnLeft[0]);
  693.  
  694.             SZ_SetAbsoluteTop(2);
  695.             SZ_SetTopEdge(2);
  696.  
  697.             SZ_SetWidth(ColumnWidth[0]);
  698.  
  699.             StatusInfo -> BoxArray[BoxCounter++] = Box = SZ_CreateTextBox(&StatusInfo -> BoxList,
  700.                 SZ_Lines,    2,
  701.                 SZ_AutoWidth,    TRUE,
  702.             TAG_DONE);
  703.  
  704.             SZ_SetBoxTitles(Box,LocaleString(MSG_TERMSTATUSDISPLAY_STATUS_TXT),LocaleString(MSG_TERMSTATUSDISPLAY_FONT_TXT),NULL);
  705.  
  706.             SZ_SetWidth(ColumnWidth[1]);
  707.             SZ_AddLeftOffset(ColumnLeft[1]);
  708.  
  709.             StatusInfo -> BoxArray[BoxCounter++] = Box = SZ_CreateTextBox(&StatusInfo -> BoxList,
  710.                 SZ_Lines,    2,
  711.                 SZ_AutoWidth,    TRUE,
  712.                 SZ_NewColumn,    TRUE,
  713.             TAG_DONE);
  714.  
  715.             SZ_SetBoxTitles(Box,LocaleString(MSG_TERMSTATUSDISPLAY_PROTOCOL_TXT),LocaleString(MSG_TERMSTATUSDISPLAY_TERMINAL_TXT),NULL);
  716.  
  717.             SZ_SetWidth(ColumnWidth[2]);
  718.             SZ_AddLeftOffset(ColumnLeft[2]);
  719.  
  720.             StatusInfo -> BoxArray[BoxCounter++] = Box = SZ_CreateTextBox(&StatusInfo -> BoxList,
  721.                 SZ_Lines,    2,
  722.                 SZ_AutoWidth,    TRUE,
  723.                 SZ_NewColumn,    TRUE,
  724.             TAG_DONE);
  725.  
  726.             SZ_SetBoxTitles(Box,LocaleString(MSG_TERMSTATUSDISPLAY_BAUDRATE_TXT),LocaleString(MSG_TERMSTATUSDISPLAY_PARAMETERS_TXT),NULL);
  727.  
  728.             SZ_SetWidth(ColumnWidth[3]);
  729.             SZ_AddLeftOffset(ColumnLeft[3]);
  730.  
  731.             StatusInfo -> BoxArray[BoxCounter] = Box = SZ_CreateTextBox(&StatusInfo -> BoxList,
  732.                 SZ_Lines,    2,
  733.                 SZ_AutoWidth,    TRUE,
  734.                 SZ_NewColumn,    TRUE,
  735.             TAG_DONE);
  736.  
  737.             SZ_SetBoxTitles(Box,LocaleString(MSG_TERMSTATUSDISPLAY_TIME_TXT),LocaleString(MSG_TERMSTATUSDISPLAY_ONLINE_TXT),NULL);
  738.  
  739.             if(!Box)
  740.             {
  741.                 SZ_FreeBoxes(StatusInfo -> BoxList);
  742.  
  743.                 DoSuperMethod(class,(Object *)NewGadget,OM_DISPOSE);
  744.  
  745.                 NewGadget = NULL;
  746.             }
  747.         }
  748.         else
  749.             StatusInfo -> FullWidth = SZ_BoxWidth(80) + 2 * SizeGadgetWidth;
  750.     }
  751.  
  752.         /* Install the old tag item list. */
  753.  
  754.     SetMethod -> ops_AttrList = OldTags;
  755.  
  756.     return((ULONG)NewGadget);
  757. }
  758.  
  759.     /* StatusGadgetDispatch():
  760.      *
  761.      *    Dispatch an object message.
  762.      */
  763.  
  764. STATIC ULONG __saveds __asm
  765. StatusGadgetDispatch(register __a0 struct IClass *class,register __a2 Object *object,register __a1 Msg msg)
  766. {
  767.     switch(msg -> MethodID)
  768.     {
  769.             /* Create new gadget. */
  770.  
  771.         case OM_NEW:
  772.  
  773.             return(NewStatusGadget(class,object,(struct opSet *)msg));
  774.  
  775.             /* Set attributes. */
  776.  
  777.         case OM_SET:
  778.  
  779.             return(SetStatusGadget(class,object,(struct opSet *)msg));
  780.  
  781.             /* Get attributes. */
  782.  
  783.         case OM_GET:
  784.  
  785.             return(GetStatusGadget(class,object,(struct opGet *)msg));
  786.  
  787.             /* Dispose gadget. */
  788.  
  789.         case OM_DISPOSE:
  790.  
  791.             return(DelStatusGadget(class,object,msg));
  792.  
  793.             /* Render the gadget. */
  794.  
  795.         case GM_RENDER:
  796.  
  797.             return(RenderStatusGadget(class,object,(struct gpRender *)msg));
  798.  
  799.             /* Do nothing. */
  800.  
  801.         case GM_HITTEST:
  802.  
  803.             return(0);
  804.  
  805.             /* Catchall... */
  806.  
  807.         default:
  808.  
  809.             return(DoSuperMethodA(class,object,msg));
  810.     }
  811. }
  812.  
  813.     /* FreeStatusGadgetClass():
  814.      *
  815.      *    Free the private status gadget class.
  816.      */
  817.  
  818. STATIC VOID
  819. FreeStatusGadgetClass()
  820. {
  821.     if(StatusGadgetClass)
  822.     {
  823.         FreeClass(StatusGadgetClass);
  824.  
  825.         StatusGadgetClass = NULL;
  826.     }
  827. }
  828.  
  829.     /* NewStatusGadgetClass():
  830.      *
  831.      *    Create a new status gadget class.
  832.      */
  833.  
  834. STATIC BYTE
  835. NewStatusGadgetClass()
  836. {
  837.         /* Release the old instance. */
  838.  
  839.     FreeStatusGadgetClass();
  840.  
  841.         /* Localize the title texts. */
  842.  
  843.     LocalizeString(ConfigFont,MSG_TERMAUX_STANDARD_FONT_TXT,MSG_TERMAUX_IBM_FONT_TXT);
  844.     LocalizeString(ConfigEmulation,MSG_TERMAUX_ANSI_VT102_TXT,MSG_TERMAUX_HEX_TXT);
  845.     LocalizeString(ConfigParity,MSG_TERMAUX_NONE_TXT,MSG_TERMAUX_SPACE_TXT);
  846.     LocalizeString(ConfigStatus,MSG_TERMAUX_READY_TXT,MSG_TERMAUX_HANG_UP_TXT);
  847.  
  848.         /* Create the class. */
  849.  
  850.     if(StatusGadgetClass = MakeClass(NULL,GADGETCLASS,NULL,sizeof(struct StatusInfo),0))
  851.     {
  852.             /* Install the dispatcher. */
  853.  
  854.         StatusGadgetClass -> cl_Dispatcher . h_Entry = (LONG (*)())StatusGadgetDispatch;
  855.  
  856.         return(TRUE);
  857.     }
  858.     else
  859.         return(FALSE);
  860. }
  861.  
  862.     /* DeleteStatusGadget(struct Gadget *Gadget):
  863.      *
  864.      *    Delete the status gadget.
  865.      */
  866.  
  867. VOID
  868. DeleteStatusGadget(struct Gadget *Gadget)
  869. {
  870.     DisposeObject(Gadget);
  871.  
  872.     FreeStatusGadgetClass();
  873. }
  874.  
  875.     /* CreateStatusGadget(LONG Width,LONG ID):
  876.      *
  877.      *    Create the status gadget.
  878.      */
  879.  
  880. struct Gadget *
  881. CreateStatusGadget(LONG Width,LONG ID)
  882. {
  883.         /* Create the new class. */
  884.  
  885.     if(NewStatusGadgetClass())
  886.     {
  887.         struct Gadget    *Gadget;
  888.         UBYTE         Mode;
  889.  
  890.             /* Determine the mode of operation. */
  891.  
  892.         if(Config -> ScreenConfig -> StatusLine == STATUSLINE_COMPRESSED)
  893.             Mode = MODE_WB_COMPRESSED;
  894.         else
  895.             Mode = MODE_WB_NORMAL;
  896.  
  897.             /* Create the new gadget. */
  898.  
  899.         if(Gadget = NewObject(StatusGadgetClass,NULL,
  900.             GA_ID,        ID,
  901.             GA_Left,    0,
  902.             GA_Width,    Width,
  903.  
  904.             SGA_Mode,    Mode,
  905.         TAG_DONE))
  906.             return(Gadget);
  907.         else
  908.             FreeStatusGadgetClass();
  909.     }
  910.  
  911.     return(NULL);
  912. }
  913.  
  914.     /* DoStatusInfo(APTR Object,UBYTE Mode,UBYTE Type,STRPTR String):
  915.      *
  916.      *    Display information in the status line area.
  917.      */
  918.  
  919. STATIC VOID __regargs
  920. DoStatusInfo(APTR Object,UBYTE Mode,UBYTE Type,STRPTR String)
  921. {
  922.         /* What mode of operation is the status area in? */
  923.  
  924.     switch(Mode)
  925.     {
  926.             /* Uses the status gadget class. */
  927.  
  928.         case MODE_WB_NORMAL:
  929.         case MODE_WB_COMPRESSED:
  930.  
  931.             SetGadgetAttrs(Object,Window,NULL,
  932.                 SG_Status + Type,String,
  933.             TAG_DONE);
  934.  
  935.                 /* Kluge! */
  936.  
  937.             if(Kick30)
  938.                 RefreshGList(Object,Window,NULL,1);
  939.  
  940.             break;
  941.  
  942.             /* Compressed mode. */
  943.  
  944.         case MODE_SCREEN_COMPRESSED:
  945.         {
  946.             struct RastPort *RPort = Object;
  947.  
  948.             STATIC BYTE Offsets[8] =
  949.             {
  950.                  0,
  951.                 -1,    /* Not supported */
  952.                 26,
  953.                 11,
  954.                 40,
  955.                 53,
  956.                 61,
  957.                 72
  958.             };
  959.  
  960.             STATIC UBYTE Strings[8][20];
  961.             UBYTE LineBuffer[90];
  962.             LONG i,j,k,Width;
  963.  
  964.             strcpy(Strings[Type],String);
  965.  
  966.             strcpy(LineBuffer,"         ·              ·             ·            ·       ·          ·         ");
  967.  
  968.             for(i = 0 ; i < 8 ; i++)
  969.             {
  970.                 if(Offsets[i] >= 0)
  971.                 {
  972.                     j = strlen(Strings[i]);
  973.  
  974.                     for(k = 0 ; k < j ; k++)
  975.                         LineBuffer[Offsets[i] + k] = Strings[i][k];
  976.                 }
  977.             }
  978.  
  979.             Width = TextLength(RPort,LineBuffer,80);
  980.  
  981.             if(StatusLineWidth && StatusLineWidth != Width)
  982.                 SetRast(RPort,DrawInfo -> dri_Pens[TEXTPEN]);
  983.  
  984.             StatusLineWidth = Width;
  985.  
  986.             Move(RPort,(StatusWindow -> Width - Width) / 2,UserFontBase);
  987.             Text(RPort,LineBuffer,80);
  988.         }
  989.  
  990.         break;
  991.  
  992.             /* Normal mode. */
  993.  
  994.         case MODE_SCREEN_NORMAL:
  995.         {
  996.             STATIC UBYTE Codes[8][2] =
  997.             {
  998.                 STATUSBOX_STATUS_FONT,        0,
  999.                 STATUSBOX_STATUS_FONT,        1,
  1000.  
  1001.                 STATUSBOX_PROTOCOL_TERMINAL,    0,
  1002.                 STATUSBOX_PROTOCOL_TERMINAL,    1,
  1003.  
  1004.                 STATUSBOX_RATE_PARAMETERS,    0,
  1005.                 STATUSBOX_RATE_PARAMETERS,    1,
  1006.  
  1007.                 STATUSBOX_TIME_ONLINE,        0,
  1008.                 STATUSBOX_TIME_ONLINE,        1
  1009.             };
  1010.  
  1011.             struct ObjectCarrier *Carrier = (struct ObjectCarrier *)Object;
  1012.  
  1013.             SZ_PrintLine(Carrier -> RPort,Carrier -> BoxArray[Codes[Type][0]],Codes[Type][1],String);
  1014.         }
  1015.  
  1016.         break;
  1017.     }
  1018. }
  1019.  
  1020.     /* DoInfo(APTR Object,UBYTE Mode,UBYTE Type,STRPTR String):
  1021.      *
  1022.      *    Post an update message to the status display server.
  1023.      */
  1024.  
  1025. STATIC VOID __regargs
  1026. DoInfo(APTR Object,UBYTE Mode,UBYTE Type,STRPTR String)
  1027. {
  1028.     struct UpdateMessage    *Msg;
  1029.     WORD             Len = strlen(String) + 1;
  1030.  
  1031.         /* Allocate enough space to hold both the string
  1032.          * and the message.
  1033.          */
  1034.  
  1035.     if(Msg = (struct UpdateMessage *)AllocVec(sizeof(struct UpdateMessage) + Len,MEMF_ANY | MEMF_PUBLIC | MEMF_CLEAR))
  1036.     {
  1037.             /* Fill in the message head. */
  1038.  
  1039.         Msg -> VanillaMessage . mn_Length = sizeof(struct UpdateMessage) + Len;
  1040.  
  1041.             /* Set up the name pointer. */
  1042.  
  1043.         Msg -> VanillaMessage . mn_Node . ln_Name = (STRPTR)(Msg + 1);
  1044.  
  1045.             /* Copy the string. */
  1046.  
  1047.         strcpy(Msg -> VanillaMessage . mn_Node . ln_Name,String);
  1048.  
  1049.             /* Fill in the remaining data. */
  1050.  
  1051.         Msg -> Object    = Object;
  1052.         Msg -> Mode    = Mode;
  1053.         Msg -> Type    = Type;
  1054.  
  1055.             /* Post the message. */
  1056.  
  1057.         PutMsg(StatusDisplayPort,(struct Message *)Msg);
  1058.     }
  1059. }
  1060.  
  1061.     /* UpdateInfo(APTR Object,UBYTE Mode,UBYTE Type,...):
  1062.      *
  1063.      *    Update the information displayed in the status
  1064.      *    area.
  1065.      */
  1066.  
  1067. STATIC VOID __stdargs
  1068. UpdateInfo(APTR Object,UBYTE Mode,UBYTE Type,...)
  1069. {
  1070.     if(Object)
  1071.     {
  1072.         UBYTE     MiniBuffer[50];
  1073.         STRPTR    *String;
  1074.         LONG    *Numeral;
  1075.         va_list     VarArgs;
  1076.  
  1077.         va_start(VarArgs,Type);
  1078.  
  1079.         String    = (STRPTR *)VarArgs;
  1080.         Numeral    = (LONG *)VarArgs;
  1081.  
  1082.         switch(Type)
  1083.         {
  1084.             case INFO_STATUS:
  1085.  
  1086.                 strcpy(MiniBuffer,ConfigStatus[Numeral[0]]);
  1087.                 strcat(MiniBuffer,"         ");
  1088.  
  1089.                 MiniBuffer[9] = 0;
  1090.  
  1091.                 DoInfo(Object,Mode,Type,MiniBuffer);
  1092.  
  1093.                 break;
  1094.  
  1095.             case INFO_FONT:
  1096.  
  1097.                 if(Mode == MODE_SCREEN_NORMAL || Mode == MODE_WB_NORMAL)
  1098.                     DoInfo(Object,Mode,Type,ConfigFont[Numeral[0]]);
  1099.  
  1100.                 break;
  1101.  
  1102.             case INFO_ONLINECOST:
  1103.  
  1104.                 strcpy(MiniBuffer,String[0]);
  1105.                 strcat(MiniBuffer,"          ");
  1106.  
  1107.                 MiniBuffer[8] = 0;
  1108.  
  1109.                 DoInfo(Object,Mode,INFO_ONLINETIME,MiniBuffer);
  1110.  
  1111.                 break;
  1112.  
  1113.             case INFO_CURRENTTIME:
  1114.             case INFO_ONLINETIME:
  1115.  
  1116.                 SPrintf(MiniBuffer,"%02ld:%02ld:%02ld",Numeral[0],Numeral[1],Numeral[2]);
  1117.  
  1118.                 DoInfo(Object,Mode,Type,MiniBuffer);
  1119.  
  1120.                 break;
  1121.  
  1122.             case INFO_BAUDRATE:
  1123.  
  1124.                 if(LocaleBase)
  1125.                     SPrintf(MiniBuffer,"%lD        ",Numeral[0]);
  1126.                 else
  1127.                     SPrintf(MiniBuffer,"%ld        ",Numeral[0]);
  1128.  
  1129.                 MiniBuffer[7] = 0;
  1130.  
  1131.                 DoInfo(Object,Mode,Type,MiniBuffer);
  1132.  
  1133.                 break;
  1134.  
  1135.             case INFO_PROTOCOL:
  1136.             case INFO_EMULATION:
  1137.  
  1138.                 strcpy(MiniBuffer,String[0]);
  1139.  
  1140.                 strcat(MiniBuffer,"           ");
  1141.  
  1142.                 MiniBuffer[12] = 0;
  1143.  
  1144.                 DoInfo(Object,Mode,Type,MiniBuffer);
  1145.  
  1146.                 break;
  1147.  
  1148.             case INFO_PARAMETERS:
  1149.  
  1150.                 if(Mode == MODE_SCREEN_COMPRESSED || Mode == MODE_WB_COMPRESSED)
  1151.                 {
  1152.                     STATIC UBYTE Parities[5] =
  1153.                     {
  1154.                         'N','E','O','M','S'
  1155.                     };
  1156.  
  1157.                     SPrintf(MiniBuffer,"%ld-%lc-%ld",Numeral[0],Parities[Numeral[1]],Numeral[2]);
  1158.                 }
  1159.                 else
  1160.                     SPrintf(MiniBuffer,"%ld-%s-%ld",Numeral[0],ConfigParity[Numeral[1]],Numeral[2]);
  1161.  
  1162.                 DoInfo(Object,Mode,Type,MiniBuffer);
  1163.  
  1164.                 break;
  1165.         }
  1166.  
  1167.         va_end(VarArgs);
  1168.     }
  1169. }
  1170.  
  1171.     /* Raise(UWORD Colour):
  1172.      *
  1173.      *    Make an RGB value brighter.
  1174.      */
  1175.  
  1176. STATIC UWORD __inline
  1177. Raise(UWORD Colour)
  1178. {
  1179.     UWORD R,G,B;
  1180.  
  1181.     R =  (Colour >> 8)        + 4;
  1182.     G = ((Colour >> 4) & 0xF) + 4;
  1183.     B = ((Colour     ) & 0xF) + 4;
  1184.  
  1185.     if(R > 15)
  1186.         R = 15;
  1187.  
  1188.     if(G > 15)
  1189.         G = 15;
  1190.  
  1191.     if(B > 15)
  1192.         B = 15;
  1193.  
  1194.     return((UWORD)(R << 8 | G << 4 | B));
  1195. }
  1196.  
  1197.     /* VisualBeep():
  1198.      *
  1199.      *    Handle the visual part of the display beep.
  1200.      */
  1201.  
  1202. STATIC BYTE
  1203. VisualBeep(VOID)
  1204. {
  1205.     struct UCopList    *UserCopperList;
  1206.  
  1207.         /* Create a user copper list. */
  1208.  
  1209.     if(UserCopperList = (struct UCopList *)AllocMem(sizeof(struct UCopList),MEMF_ANY|MEMF_CLEAR))
  1210.     {
  1211.             /* Initialize for 35 commands. */
  1212.  
  1213.         if(UCopperListInit(UserCopperList,1 + 16 + 1 + 16 + 1))
  1214.         {
  1215.             WORD i;
  1216.  
  1217.                 /* Wait until first line of window. */
  1218.  
  1219.             CWAIT(UserCopperList,Window -> TopEdge,0);
  1220.  
  1221.                 /* Set the light colours. */
  1222.  
  1223.             for(i = 0 ; i < 16 ; i++)
  1224.                 CMOVE(UserCopperList,custom . color[i],Raise(GetRGB4(Screen -> ViewPort . ColorMap,i)));
  1225.  
  1226.                 /* Wait until bottom of window. */
  1227.  
  1228.             CWAIT(UserCopperList,Window -> TopEdge + Window -> Height - 1,0);
  1229.  
  1230.                 /* Set the standard colours. */
  1231.  
  1232.             for(i = 0 ; i < 16 ; i++)
  1233.                 CMOVE(UserCopperList,custom . color[i],GetRGB4(Screen -> ViewPort . ColorMap,i));
  1234.  
  1235.                 /* Finish list. */
  1236.  
  1237.             CEND(UserCopperList);
  1238.  
  1239.                 /* Install user copper list... */
  1240.  
  1241.             Screen -> ViewPort . UCopIns = UserCopperList;
  1242.  
  1243.                 /* ...and display it. */
  1244.  
  1245.             RethinkDisplay();
  1246.  
  1247.             return(TRUE);
  1248.         }
  1249.         else
  1250.             FreeMem(UserCopperList,sizeof(struct UCopList));
  1251.     }
  1252.  
  1253.     return(FALSE);
  1254. }
  1255.  
  1256.     /* StatusDisplayServer(VOID):
  1257.      *
  1258.      *    Yet another asynchronous background task to display
  1259.      *    some information.
  1260.      */
  1261.  
  1262. STATIC VOID __saveds
  1263. StatusDisplayServer(VOID)
  1264. {
  1265.         /* Create the interface port. */
  1266.  
  1267.     if(StatusDisplayPort = CreateMsgPort())
  1268.     {
  1269.         struct UpdateMessage    *Msg;
  1270.         ULONG             Signals;
  1271.  
  1272.             /* Ring back... */
  1273.  
  1274.         Signal(StatusProcess,SIG_HANDSHAKE);
  1275.  
  1276.             /* Wait for messages or termination signal. */
  1277.  
  1278.         FOREVER
  1279.         {
  1280.             Signals = Wait(SIG_KILL | PORTMASK(StatusDisplayPort));
  1281.  
  1282.                 /* Termination? */
  1283.  
  1284.             if(Signals & SIG_KILL)
  1285.                 break;
  1286.  
  1287.                 /* Message arrival? */
  1288.  
  1289.             if(Signals & PORTMASK(StatusDisplayPort))
  1290.             {
  1291.                     /* Process all pending messages. */
  1292.  
  1293.                 while(Msg = (struct UpdateMessage *)GetMsg(StatusDisplayPort))
  1294.                 {
  1295.                     DoStatusInfo(Msg -> Object,Msg -> Mode,Msg -> Type,Msg -> VanillaMessage . mn_Node . ln_Name);
  1296.  
  1297.                     FreeVec(Msg);
  1298.                 }
  1299.             }
  1300.         }
  1301.  
  1302.             /* Remove all pending messages. */
  1303.  
  1304.         while(Msg = (struct UpdateMessage *)GetMsg(StatusDisplayPort))
  1305.             FreeVec(Msg);
  1306.  
  1307.             /* Remove the msgport. */
  1308.  
  1309.         DeleteMsgPort(StatusDisplayPort);
  1310.     }
  1311.  
  1312.         /* Lock & quit... */
  1313.  
  1314.     Forbid();
  1315.  
  1316.     Signal(StatusProcess,SIG_HANDSHAKE);
  1317.  
  1318.     RemTask(StatusDisplayTask = NULL);
  1319. }
  1320.  
  1321.     /* StatusServer():
  1322.      *
  1323.      *    Asynchronous process to continuosly display the current
  1324.      *    terminal settings.
  1325.      */
  1326.  
  1327. VOID __saveds
  1328. StatusServer()
  1329. {
  1330.     STATIC struct timeval     OnlineTime,
  1331.                  LastTime,
  1332.                  TempTime;
  1333.     STATIC BYTE         GotOnline        = FALSE,
  1334.                  WasOnline        = FALSE,
  1335.                  ShowPay        = FALSE,
  1336.                  FlagBit        = FALSE;
  1337.     STATIC LONG         SecCount        = 0,
  1338.                  MinCount        = 0,
  1339.                  BeepCount        = 0;
  1340.  
  1341.     struct TextBox        *BoxArray[4],
  1342.                 *BoxList = NULL,
  1343.                 *Box;
  1344.  
  1345.     struct RastPort        *RPort;
  1346.  
  1347.     APTR             SomeObject;
  1348.     struct ObjectCarrier     Carrier;
  1349.  
  1350.     struct timerequest    *StatusTimeRequest;
  1351.     struct MsgPort        *StatusTimePort;
  1352.  
  1353.     BYTE             Background        = FALSE,
  1354.                  FlashIt        = FALSE,
  1355.                  SetColours        = FALSE,
  1356.                  StandardColours    = TRUE,
  1357.                  KeepGoing        = TRUE,
  1358.                  Beeping        = FALSE,
  1359.                  StatusMode        = Config -> ScreenConfig -> StatusLine;
  1360.  
  1361.     BYTE             LastProtocol[40],
  1362.                  ProtocolBuffer[40],
  1363.                  LastEmulationName[40];
  1364.  
  1365.     BYTE             LastFont        = -1,
  1366.                  LastEmulation        = -1,
  1367.                  LastBitsPerChar    = -1,
  1368.                  LastParity        = -1,
  1369.                  LastStopBits        = -1,
  1370.                  LastStatus        = -1;
  1371.  
  1372.     LONG             LastBaud        = -1;
  1373.  
  1374.     LONG             i,
  1375.                  ThisHour,
  1376.                  ThisMinute,
  1377.                  BoxCounter = 0,
  1378.                  FullWidth;
  1379.     WORD             ColumnLeft[4],
  1380.                  ColumnWidth[4],
  1381.                  Max,
  1382.                  Len;
  1383.     BYTE             AllFine = TRUE;
  1384.     UBYTE             Mode;
  1385.  
  1386.     StatusLineWidth = 0;
  1387.  
  1388.     LastProtocol[0] = 0;
  1389.  
  1390.     LastEmulationName[0] = 0;
  1391.  
  1392.     LocalizeString(ConfigFont,MSG_TERMAUX_STANDARD_FONT_TXT,MSG_TERMAUX_IBM_FONT_TXT);
  1393.     LocalizeString(ConfigEmulation,MSG_TERMAUX_ANSI_VT102_TXT,MSG_TERMAUX_HEX_TXT);
  1394.     LocalizeString(ConfigParity,MSG_TERMAUX_NONE_TXT,MSG_TERMAUX_SPACE_TXT);
  1395.     LocalizeString(ConfigStatus,MSG_TERMAUX_READY_TXT,MSG_TERMAUX_HANG_UP_TXT);
  1396.  
  1397.     if(StatusWindow)
  1398.     {
  1399.         RPort = StatusWindow -> RPort;
  1400.  
  1401.             /* Render the information. */
  1402.  
  1403.         SZ_SizeSetup(Screen,&UserFont,TRUE);
  1404.  
  1405.         if(StatusMode == STATUSLINE_COMPRESSED)
  1406.         {
  1407.             StatusOffset = (Screen -> Width - 80 * UserFontWidth) / 2;
  1408.  
  1409.             SetAPen(RPort,DrawInfo -> dri_Pens[TEXTPEN]);
  1410.  
  1411.             RectFill(RPort,0,0,StatusWindow -> Width - 1,StatusWindow -> Height - 1);
  1412.  
  1413.             SetAPen(RPort,0);
  1414.             SetBPen(RPort,DrawInfo -> dri_Pens[TEXTPEN]);
  1415.         }
  1416.         else
  1417.         {
  1418.             SetAPen(RPort,DrawInfo -> dri_Pens[TEXTPEN]);
  1419.             SetBPen(RPort,0);
  1420.  
  1421.                 /* Draw a separating line. */
  1422.  
  1423.             Move(RPort,0,0);
  1424.             Draw(RPort,StatusWindow -> Width - 1,0);
  1425.  
  1426.             ColumnLeft[0] = SZ_LeftOffsetN(MSG_TERMSTATUSDISPLAY_STATUS_TXT,MSG_TERMSTATUSDISPLAY_FONT_TXT,-1);
  1427.             ColumnLeft[1] = SZ_LeftOffsetN(MSG_TERMSTATUSDISPLAY_PROTOCOL_TXT,MSG_TERMSTATUSDISPLAY_TERMINAL_TXT,-1);
  1428.             ColumnLeft[2] = SZ_LeftOffsetN(MSG_TERMSTATUSDISPLAY_BAUDRATE_TXT,MSG_TERMSTATUSDISPLAY_PARAMETERS_TXT,-1);
  1429.             ColumnLeft[3] = SZ_LeftOffsetN(MSG_TERMSTATUSDISPLAY_TIME_TXT,MSG_TERMSTATUSDISPLAY_ONLINE_TXT,-1);
  1430.  
  1431.             Max = 0;
  1432.  
  1433.             for(i = 0 ; ConfigStatus[i] ; i++)
  1434.             {
  1435.                 if((Len = SZ_BoxWidth(strlen(ConfigStatus[i]))) > Max)
  1436.                     Max = Len;
  1437.             }
  1438.  
  1439.             for(i = 0 ; ConfigFont[i] ; i++)
  1440.             {
  1441.                 if((Len = SZ_BoxWidth(strlen(ConfigFont[i]))) > Max)
  1442.                     Max = Len;
  1443.             }
  1444.  
  1445.             ColumnWidth[0] = Max;
  1446.  
  1447.             Max = SZ_BoxWidth(12);
  1448.  
  1449.             for(i = 0 ; ConfigEmulation[i] ; i++)
  1450.             {
  1451.                 if((Len = SZ_BoxWidth(strlen(ConfigEmulation[i]))) > Max)
  1452.                     Max = Len;
  1453.             }
  1454.  
  1455.             ColumnWidth[1] = Max;
  1456.  
  1457.             Max = SZ_BoxWidth(10);
  1458.  
  1459.             for(i = 0 ; ConfigParity[i] ; i++)
  1460.             {
  1461.                 if((Len = SZ_BoxWidth(4 + strlen(ConfigParity[i]))) > Max)
  1462.                     Max = Len;
  1463.             }
  1464.  
  1465.             ColumnWidth[2] = Max;
  1466.  
  1467.             ColumnWidth[3] = SZ_BoxWidth(8);
  1468.  
  1469.             FullWidth = 0;
  1470.  
  1471.             for(i = 0 ; i < 4 ; i++)
  1472.                 FullWidth += ColumnWidth[i] + ColumnLeft[i];
  1473.  
  1474.             FullWidth += 3 * InterWidth;
  1475.  
  1476.             if(FullWidth > Screen -> Width)
  1477.                 SZ_SetLeftEdge(ColumnLeft[0]);
  1478.             else
  1479.                 SZ_SetLeftEdge((Screen -> Width - FullWidth) / 2 + ColumnLeft[0]);
  1480.  
  1481.             SZ_SetAbsoluteTop(2);
  1482.             SZ_SetTopEdge(2);
  1483.  
  1484.             SZ_SetWidth(ColumnWidth[0]);
  1485.  
  1486.             BoxArray[BoxCounter++] = Box = SZ_CreateTextBox(&BoxList,
  1487.                 SZ_Lines,    2,
  1488.                 SZ_AutoWidth,    TRUE,
  1489.             TAG_DONE);
  1490.  
  1491.             SZ_SetBoxTitles(Box,LocaleString(MSG_TERMSTATUSDISPLAY_STATUS_TXT),LocaleString(MSG_TERMSTATUSDISPLAY_FONT_TXT),NULL);
  1492.  
  1493.             SZ_SetWidth(ColumnWidth[1]);
  1494.             SZ_AddLeftOffset(ColumnLeft[1]);
  1495.  
  1496.             BoxArray[BoxCounter++] = Box = SZ_CreateTextBox(&BoxList,
  1497.                 SZ_Lines,    2,
  1498.                 SZ_AutoWidth,    TRUE,
  1499.                 SZ_NewColumn,    TRUE,
  1500.             TAG_DONE);
  1501.  
  1502.             SZ_SetBoxTitles(Box,LocaleString(MSG_TERMSTATUSDISPLAY_PROTOCOL_TXT),LocaleString(MSG_TERMSTATUSDISPLAY_TERMINAL_TXT),NULL);
  1503.  
  1504.             SZ_SetWidth(ColumnWidth[2]);
  1505.             SZ_AddLeftOffset(ColumnLeft[2]);
  1506.  
  1507.             BoxArray[BoxCounter++] = Box = SZ_CreateTextBox(&BoxList,
  1508.                 SZ_Lines,    2,
  1509.                 SZ_AutoWidth,    TRUE,
  1510.                 SZ_NewColumn,    TRUE,
  1511.             TAG_DONE);
  1512.  
  1513.             SZ_SetBoxTitles(Box,LocaleString(MSG_TERMSTATUSDISPLAY_BAUDRATE_TXT),LocaleString(MSG_TERMSTATUSDISPLAY_PARAMETERS_TXT),NULL);
  1514.  
  1515.             SZ_SetWidth(ColumnWidth[3]);
  1516.             SZ_AddLeftOffset(ColumnLeft[3]);
  1517.  
  1518.             BoxArray[BoxCounter] = Box = SZ_CreateTextBox(&BoxList,
  1519.                 SZ_Lines,    2,
  1520.                 SZ_AutoWidth,    TRUE,
  1521.                 SZ_NewColumn,    TRUE,
  1522.             TAG_DONE);
  1523.  
  1524.             SZ_SetBoxTitles(Box,LocaleString(MSG_TERMSTATUSDISPLAY_TIME_TXT),LocaleString(MSG_TERMSTATUSDISPLAY_ONLINE_TXT),NULL);
  1525.  
  1526.             if(!Box)
  1527.                 AllFine = FALSE;
  1528.             else
  1529.                 SZ_DrawBoxes(RPort,BoxList);
  1530.         }
  1531.     }
  1532.     else
  1533.     {
  1534.         if(Config -> ScreenConfig -> UseWorkbench && StatusGadget)
  1535.             AllFine = TRUE;
  1536.     }
  1537.  
  1538.         /* Everything fine so far? */
  1539.  
  1540.     if(AllFine)
  1541.     {
  1542.         Forbid();
  1543.  
  1544.             /* Create the display server task. */
  1545.  
  1546.         if(StatusDisplayTask = CreateTask("term status display task",5,StatusDisplayServer,4000))
  1547.         {
  1548.             ClrSignal(SIG_HANDSHAKE);
  1549.  
  1550.             Wait(SIG_HANDSHAKE);
  1551.         }
  1552.  
  1553.         Permit();
  1554.     }
  1555.  
  1556.         /* Is the display server task up and running? */
  1557.  
  1558.     if(StatusDisplayTask)
  1559.     {
  1560.             /* Create a timer device request. */
  1561.  
  1562.         if(StatusTimePort = (struct MsgPort *)CreateMsgPort())
  1563.         {
  1564.             if(StatusTimeRequest = (struct timerequest *)CreateIORequest(StatusTimePort,sizeof(struct timerequest)))
  1565.             {
  1566.                 if(!OpenDevice(TIMERNAME,UNIT_VBLANK,StatusTimeRequest,0))
  1567.                 {
  1568.                         /* Signal our father process
  1569.                          * that we're running.
  1570.                          */
  1571.  
  1572.                     Signal(ThisProcess,SIG_HANDSHAKE);
  1573.  
  1574.                     if(StatusWindow)
  1575.                     {
  1576.                         if(StatusMode == STATUSLINE_COMPRESSED)
  1577.                         {
  1578.                             Mode = MODE_SCREEN_COMPRESSED;
  1579.  
  1580.                             SomeObject = RPort;
  1581.                         }
  1582.                         else
  1583.                         {
  1584.                             Mode = MODE_SCREEN_NORMAL;
  1585.  
  1586.                             Carrier . RPort        = RPort;
  1587.                             Carrier . BoxArray    = BoxArray;
  1588.  
  1589.                             SomeObject = &Carrier;
  1590.                         }
  1591.  
  1592.                         UpdateInfo(SomeObject,Mode,INFO_ONLINETIME,0,0,0);
  1593.                     }
  1594.                     else
  1595.                     {
  1596.                         if(StatusGadget)
  1597.                         {
  1598.                             SomeObject = StatusGadget;
  1599.  
  1600.                             if(StatusMode == STATUSLINE_COMPRESSED)
  1601.                                 Mode = MODE_WB_COMPRESSED;
  1602.                             else
  1603.                                 Mode = MODE_WB_NORMAL;
  1604.  
  1605.                             UpdateInfo(SomeObject,Mode,INFO_ONLINETIME,0,0,0);
  1606.                         }
  1607.                         else
  1608.                             SomeObject = NULL;
  1609.                     }
  1610.  
  1611.                         /* Keep on displaying. */
  1612.  
  1613.                     while(KeepGoing)
  1614.                     {
  1615.                             /* Are we to quit? */
  1616.  
  1617.                         if(CheckSignal(SIG_KILL))
  1618.                             KeepGoing = FALSE;
  1619.  
  1620.                             /* Get the current time. */
  1621.  
  1622.                         StatusTimeRequest -> tr_node . io_Command = TR_GETSYSTIME;
  1623.  
  1624.                         DoIO(StatusTimeRequest);
  1625.  
  1626.                             /* A connection has just
  1627.                              * been established.
  1628.                              */
  1629.  
  1630.                         if(Online && !GotOnline)
  1631.                         {
  1632.                             OnlineTime = StatusTimeRequest -> tr_time;
  1633.  
  1634.                                 /* Add up connection time. */
  1635.  
  1636.                             if(OnlinePlus)
  1637.                             {
  1638.                                 struct timeval GetBack;
  1639.  
  1640.                                 GetBack . tv_secs    = (OnlinePlus / 6) * 60 + (OnlinePlus % 6) * 10;
  1641.                                 GetBack . tv_micro    = 0;
  1642.  
  1643.                                 OnlinePlus = 0;
  1644.  
  1645.                                 SubTime(&OnlineTime,&GetBack);
  1646.                             }
  1647.  
  1648.                             GotOnline = TRUE;
  1649.  
  1650.                             SecCount = 0;
  1651.  
  1652.                             FlagBit = FALSE;
  1653.                         }
  1654.  
  1655.                             /* Print the current time. */
  1656.  
  1657.                         ThisHour    = (StatusTimeRequest -> tr_time . tv_secs % 86400) / 3600;
  1658.                         ThisMinute    = (StatusTimeRequest -> tr_time . tv_secs % 3600) / 60;
  1659.  
  1660.                         UpdateInfo(SomeObject,Mode,INFO_CURRENTTIME,ThisHour,ThisMinute,StatusTimeRequest -> tr_time . tv_secs % 60);
  1661.  
  1662.                             /* Handle routine checkup actions. */
  1663.  
  1664.                         if(!(SecCount & 1))
  1665.                             Signal(ThisProcess,SIG_CHECK);
  1666.  
  1667.                         if(Online)
  1668.                         {
  1669.                             WasOnline = TRUE;
  1670.  
  1671.                             if(ChosenEntry)
  1672.                             {
  1673.                                 if(!(ThisMinute % 10) && !(StatusTimeRequest -> tr_time . tv_secs % 60))
  1674.                                 {
  1675.                                     ChosenInUse = TRUE;
  1676.  
  1677.                                     SelectTime(ChosenEntry);
  1678.  
  1679.                                     ChosenInUse = FALSE;
  1680.                                 }
  1681.  
  1682.                                 if(!CurrentPay)
  1683.                                     CurrentPay = PayPerUnit[DT_FIRST_UNIT];
  1684.  
  1685.                                 FlagBit ^= TRUE;
  1686.  
  1687.                                 if(!FlagBit)
  1688.                                 {
  1689.                                     if(SecPerUnit[WhichUnit] && SecCount == SecPerUnit[WhichUnit])
  1690.                                     {
  1691.                                         SecCount = 0;
  1692.  
  1693.                                         WhichUnit = DT_NEXT_UNIT;
  1694.  
  1695.                                         CurrentPay += PayPerUnit[DT_NEXT_UNIT];
  1696.                                     }
  1697.  
  1698.                                     SecCount++;
  1699.                                 }
  1700.                             }
  1701.  
  1702.                                 /* Show the time
  1703.                                  * we have been online
  1704.                                  * yet.
  1705.                                  */
  1706.  
  1707.                             TempTime = StatusTimeRequest -> tr_time;
  1708.  
  1709.                             SubTime(&TempTime,&OnlineTime);
  1710.  
  1711.                             if(StatusTimeRequest -> tr_time . tv_secs != LastTime . tv_secs)
  1712.                             {
  1713.                                 LastTime = StatusTimeRequest -> tr_time;
  1714.  
  1715.                                 switch(Config -> ScreenConfig -> TimeMode)
  1716.                                 {
  1717.                                     case ONLINETIME_TIME:    ShowPay = FALSE;
  1718.                                                 break;
  1719.  
  1720.                                     case ONLINETIME_COST:    ShowPay = TRUE;
  1721.                                                 break;
  1722.  
  1723.                                     case ONLINETIME_BOTH:    if(TempTime . tv_secs && !(TempTime . tv_secs % 5))
  1724.                                                     ShowPay ^= TRUE;
  1725.  
  1726.                                                 break;
  1727.                                 }
  1728.  
  1729.                                 if(ShowPay && ChosenEntry)
  1730.                                     UpdateInfo(SomeObject,Mode,INFO_ONLINECOST,CreateSum(CurrentPay,FALSE));
  1731.                                 else
  1732.                                     UpdateInfo(SomeObject,Mode,INFO_ONLINETIME,(TempTime . tv_secs % 86400) / 3600,(TempTime . tv_secs % 3600) / 60,TempTime . tv_secs % 60);
  1733.  
  1734.                                 OnlineMinutes = TempTime . tv_secs / 60;
  1735.                             }
  1736.                         }
  1737.                         else
  1738.                         {
  1739.                             if(WasOnline)
  1740.                             {
  1741.                                 WasOnline = FALSE;
  1742.  
  1743.                                 UpdateInfo(SomeObject,Mode,INFO_ONLINETIME,(TempTime . tv_secs % 86400) / 3600,(TempTime . tv_secs % 3600) / 60,TempTime . tv_secs % 60);
  1744.                             }
  1745.  
  1746.                             if(GotOnline)
  1747.                                 GotOnline = FALSE;
  1748.                         }
  1749.  
  1750.                             /* Take care of the visual beep
  1751.                              * if enabled.
  1752.                              */
  1753.  
  1754.                         if(Beeping)
  1755.                         {
  1756.                             if(!(BeepCount--))
  1757.                             {
  1758.                                 Beeping = FALSE;
  1759.  
  1760.                                     /* Remove the copper list. */
  1761.  
  1762.                                 FreeVPortCopLists(&Screen -> ViewPort);
  1763.  
  1764.                                     /* Really remove it. */
  1765.  
  1766.                                 RemakeDisplay();
  1767.  
  1768.                                     /* Clear the signal bit. */
  1769.  
  1770.                                 ClrSignal(SIG_BELL);
  1771.                             }
  1772.                         }
  1773.  
  1774.                             /* Are we to show a visual beep? */
  1775.  
  1776.                         if(CheckSignal(SIG_BELL))
  1777.                         {
  1778.                             if(Config -> TerminalConfig -> BellMode == BELL_SYSTEM)
  1779.                                 DisplayBeep(Window -> WScreen);
  1780.                             else
  1781.                             {
  1782.                                 if(Screen && !Config -> ScreenConfig -> UseWorkbench && !Beeping && (Config -> TerminalConfig -> BellMode == BELL_VISIBLE || Config -> TerminalConfig -> BellMode == BELL_BOTH))
  1783.                                 {
  1784.                                     if(VisualBeep())
  1785.                                     {
  1786.                                         Beeping = TRUE;
  1787.  
  1788.                                         BeepCount = 1;
  1789.                                     }
  1790.                                 }
  1791.                             }
  1792.                         }
  1793.  
  1794.                             /* Display the current terminal
  1795.                              * status.
  1796.                              */
  1797.  
  1798.                         if(LastStatus != Status)
  1799.                             UpdateInfo(SomeObject,Mode,INFO_STATUS,LastStatus = Status);
  1800.  
  1801.                             /* Show the current transfer
  1802.                              * protocol.
  1803.                              */
  1804.  
  1805.                         if(strcmp(LastProtocol,FilePart(Config -> FileConfig -> ProtocolFileName)))
  1806.                         {
  1807.                             strcpy(LastProtocol,FilePart(Config -> FileConfig -> ProtocolFileName));
  1808.  
  1809.                             if((Len = strlen(LastProtocol)) > 3)
  1810.                             {
  1811.                                 strcpy(ProtocolBuffer,&LastProtocol[3]);
  1812.  
  1813.                                 for(i = 0 ; i < Len - 3 ; i++)
  1814.                                 {
  1815.                                     if(ProtocolBuffer[i] == '.')
  1816.                                     {
  1817.                                         ProtocolBuffer[i] = 0;
  1818.  
  1819.                                         break;
  1820.                                     }
  1821.                                 }
  1822.  
  1823.                                 UpdateInfo(SomeObject,Mode,INFO_PROTOCOL,ProtocolBuffer);
  1824.                             }
  1825.                         }
  1826.  
  1827.                             /* Show the current baud
  1828.                              * rate.
  1829.                              */
  1830.  
  1831.                         if(LastBaud != Config -> SerialConfig -> BaudRate)
  1832.                             UpdateInfo(SomeObject,Mode,INFO_BAUDRATE,LastBaud = Config -> SerialConfig -> BaudRate);
  1833.  
  1834.                             /* Show the current
  1835.                              * terminal font.
  1836.                              */
  1837.  
  1838.                         if(LastFont != Config -> TerminalConfig -> FontMode)
  1839.                         {
  1840.                             LastFont = Config -> TerminalConfig -> FontMode;
  1841.  
  1842.                             UpdateInfo(SomeObject,Mode,INFO_FONT,LastFont != FONT_STANDARD);
  1843.                         }
  1844.  
  1845.                             /* Show the current terminal
  1846.                              * emulation.
  1847.                              */
  1848.  
  1849.                         if(LastEmulation != Config -> TerminalConfig -> EmulationMode || (Config -> TerminalConfig -> EmulationMode == EMULATION_EXTERNAL && Stricmp(EmulationName,LastEmulationName)))
  1850.                         {
  1851.                             LastEmulation = Config -> TerminalConfig -> EmulationMode;
  1852.  
  1853.                             if(Config -> TerminalConfig -> EmulationMode == EMULATION_EXTERNAL)
  1854.                             {
  1855.                                 UpdateInfo(SomeObject,Mode,INFO_EMULATION,EmulationName);
  1856.  
  1857.                                 strcpy(LastEmulationName,EmulationName);
  1858.                             }
  1859.                             else
  1860.                                 UpdateInfo(SomeObject,Mode,INFO_EMULATION,ConfigEmulation[LastEmulation]);
  1861.                         }
  1862.  
  1863.                             /* Show the current serial
  1864.                              * parameters (parity, etc).
  1865.                              */
  1866.  
  1867.                         if(LastBitsPerChar != Config -> SerialConfig -> BitsPerChar || LastParity != Config -> SerialConfig -> Parity || LastStopBits != Config -> SerialConfig -> StopBits)
  1868.                         {
  1869.                             LastBitsPerChar    = Config -> SerialConfig -> BitsPerChar;
  1870.                             LastParity    = Config -> SerialConfig -> Parity;
  1871.                             LastStopBits    = Config -> SerialConfig -> StopBits;
  1872.  
  1873.                             UpdateInfo(SomeObject,Mode,INFO_PARAMETERS,LastBitsPerChar,LastParity,LastStopBits);
  1874.                         }
  1875.  
  1876.                             /* Wait another half a second. */
  1877.  
  1878.                         if(KeepGoing)
  1879.                         {
  1880.                             ULONG Mask;
  1881.  
  1882.                             StatusTimeRequest -> tr_node . io_Command    = TR_ADDREQUEST;
  1883.                             StatusTimeRequest -> tr_time . tv_secs        = 0;
  1884.                             StatusTimeRequest -> tr_time . tv_micro        = MILLION / 2;
  1885.  
  1886.                             SendIO(StatusTimeRequest);
  1887.  
  1888.                             FOREVER
  1889.                             {
  1890.                                 Mask = Wait(SIG_BELL | PORTMASK(StatusTimePort));
  1891.  
  1892.                                 if(Mask & SIG_BELL)
  1893.                                 {
  1894.                                     if(Config -> TerminalConfig -> BellMode == BELL_SYSTEM)
  1895.                                         DisplayBeep(Window -> WScreen);
  1896.                                     else
  1897.                                     {
  1898.                                         if(Screen && !Config -> ScreenConfig -> UseWorkbench && !Beeping && (Config -> TerminalConfig -> BellMode == BELL_VISIBLE || Config -> TerminalConfig -> BellMode == BELL_BOTH))
  1899.                                         {
  1900.                                             if(VisualBeep())
  1901.                                             {
  1902.                                                 Beeping = TRUE;
  1903.  
  1904.                                                 BeepCount = 1;
  1905.                                             }
  1906.                                         }
  1907.                                     }
  1908.                                 }
  1909.  
  1910.                                 if(Mask & PORTMASK(StatusTimePort))
  1911.                                 {
  1912.                                     WaitIO(StatusTimeRequest);
  1913.  
  1914.                                     break;
  1915.                                 }
  1916.                             }
  1917.  
  1918.                                 /* Count up to a minute. */
  1919.  
  1920.                             if(MinCount++ == 120)
  1921.                             {
  1922.                                 MinCount = 0;
  1923.  
  1924.                                     /* Time limit present? */
  1925.  
  1926.                                 if(LimitCount > 0)
  1927.                                     LimitCount--;
  1928.  
  1929.                                     /* Limit reached? */
  1930.  
  1931.                                 if(!LimitCount)
  1932.                                     Signal(ThisProcess,SIG_CHECK);
  1933.                             }
  1934.                         }
  1935.  
  1936.                             /* Make the colours blink. */
  1937.  
  1938.                         if(Screen && !Config -> ScreenConfig -> UseWorkbench)
  1939.                         {
  1940.                             if(Screen == IntuitionBase -> FirstScreen)
  1941.                             {
  1942.                                     /* No main screen window active? */
  1943.     
  1944.                                 if(StatusWindow)
  1945.                                 {
  1946.                                     if(!(Window -> Flags & WFLG_WINDOWACTIVE) && !(StatusWindow -> Flags & WFLG_WINDOWACTIVE))
  1947.                                         StandardColours = TRUE;
  1948.                                 }
  1949.                                 else
  1950.                                 {
  1951.                                     if(!(Window -> Flags & WFLG_WINDOWACTIVE))
  1952.                                         StandardColours = TRUE;
  1953.                                 }
  1954.     
  1955.                                     /* Menu button pressed or window disabled? */
  1956.     
  1957.                                 if(Window -> Flags & (WFLG_MENUSTATE | WFLG_INREQUEST))
  1958.                                     StandardColours = TRUE;
  1959.     
  1960.                                     /* User is currently dragging the
  1961.                                      * mouse in order to mark something
  1962.                                      * on the screen?
  1963.                                      */
  1964.     
  1965.                                 if(Marking)
  1966.                                     StandardColours = TRUE;
  1967.     
  1968.                                 Background = FALSE;
  1969.                             }
  1970.                             else
  1971.                             {
  1972.                                 if(!Background)
  1973.                                     StandardColours = TRUE;
  1974.     
  1975.                                 Background = TRUE;
  1976.                             }
  1977.     
  1978.                             if(StandardColours)
  1979.                             {
  1980.                                 if(!SetColours)
  1981.                                 {
  1982.                                     LoadRGB4(VPort,NormalColours,PaletteSize);
  1983.     
  1984.                                     SetColours = TRUE;
  1985.                                 }
  1986.     
  1987.                                 StandardColours = FlashIt = FALSE;
  1988.                             }
  1989.                             else
  1990.                             {
  1991.                                     /* Are we to flash the display? */
  1992.     
  1993.                                 if(Config -> ScreenConfig -> Blinking)
  1994.                                 {
  1995.                                     if(Screen == IntuitionBase -> FirstScreen)
  1996.                                     {
  1997.                                         if(FlashIt)
  1998.                                         {
  1999.                                             LoadRGB4(VPort,BlinkColours,PaletteSize);
  2000.     
  2001.                                             SetColours = FALSE;
  2002.                                         }
  2003.                                         else
  2004.                                         {
  2005.                                             LoadRGB4(VPort,NormalColours,PaletteSize);
  2006.     
  2007.                                             SetColours = TRUE;
  2008.                                         }
  2009.                                     }
  2010.     
  2011.                                     FlashIt ^= TRUE;
  2012.                                 }
  2013.                             }
  2014.                         }
  2015.                     }
  2016.  
  2017.                     CloseDevice(StatusTimeRequest);
  2018.                 }
  2019.  
  2020.                 DeleteIORequest(StatusTimeRequest);
  2021.             }
  2022.  
  2023.             DeleteMsgPort(StatusTimePort);
  2024.         }
  2025.  
  2026.         if(StatusDisplayTask)
  2027.         {
  2028.             Forbid();
  2029.  
  2030.             Signal(StatusDisplayTask,SIG_KILL);
  2031.  
  2032.             ClrSignal(SIG_HANDSHAKE);
  2033.  
  2034.             Wait(SIG_HANDSHAKE);
  2035.  
  2036.             Permit();
  2037.         }
  2038.  
  2039.         if(BoxList)
  2040.             SZ_FreeBoxes(BoxList);
  2041.     }
  2042.  
  2043.         /* Signal the father process that we're done
  2044.          * and quietly remove ourselves.
  2045.          */
  2046.  
  2047.     Forbid();
  2048.  
  2049.     Signal(ThisProcess,SIG_HANDSHAKE);
  2050.  
  2051.     StatusProcess = NULL;
  2052. }
  2053.